/**
 * 文件服务
 * 处理文件上传、下载等文件相关业务逻辑
 */

import { request } from '@/utils/request'
import { API_ENDPOINTS, UPLOAD } from '@/constants'

export class FileService {
  /**
   * 上传文件
   */
  static async uploadFile(file: File, options?: {
    onProgress?: (progress: number) => void
    folder?: string
  }): Promise<{ url: string; filename: string }> {
    try {
      // 验证文件大小
      if (file.size > UPLOAD.MAX_SIZE) {
        throw new Error(`文件大小不能超过 ${UPLOAD.MAX_SIZE / 1024 / 1024}MB`)
      }

      // 验证文件类型
      if (!UPLOAD.ALLOWED_TYPES.includes(file.type)) {
        throw new Error('不支持的文件类型')
      }

      const formData = new FormData()
      formData.append('file', file)
      
      if (options?.folder) {
        formData.append('folder', options.folder)
      }

      const response = await request.post(API_ENDPOINTS.UPLOAD, formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        onUploadProgress: (progressEvent) => {
          if (options?.onProgress && progressEvent.total) {
            const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
            options.onProgress(progress)
          }
        }
      })

      return response.data
    } catch (error) {
      console.error('上传文件失败:', error)
      throw error
    }
  }

  /**
   * 上传头像
   */
  static async uploadAvatar(file: File, options?: {
    onProgress?: (progress: number) => void
  }): Promise<{ url: string; filename: string }> {
    try {
      // 验证文件大小
      if (file.size > UPLOAD.MAX_SIZE) {
        throw new Error(`文件大小不能超过 ${UPLOAD.MAX_SIZE / 1024 / 1024}MB`)
      }

      // 验证文件类型（头像只允许图片）
      const allowedImageTypes = ['image/jpeg', 'image/png', 'image/gif']
      if (!allowedImageTypes.includes(file.type)) {
        throw new Error('头像只支持 JPG、PNG、GIF 格式')
      }

      const formData = new FormData()
      formData.append('file', file)

      const response = await request.post(API_ENDPOINTS.UPLOAD_AVATAR, formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        onUploadProgress: (progressEvent) => {
          if (options?.onProgress && progressEvent.total) {
            const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
            options.onProgress(progress)
          }
        }
      })

      return response.data
    } catch (error) {
      console.error('上传头像失败:', error)
      throw error
    }
  }

  /**
   * 下载文件
   */
  static async downloadFile(url: string, filename?: string): Promise<void> {
    try {
      const response = await request.get(url, {
        responseType: 'blob'
      })

      // 创建下载链接
      const blob = new Blob([response.data])
      const downloadUrl = window.URL.createObjectURL(blob)
      
      const link = document.createElement('a')
      link.href = downloadUrl
      link.download = filename || 'download'
      document.body.appendChild(link)
      link.click()
      
      // 清理
      document.body.removeChild(link)
      window.URL.revokeObjectURL(downloadUrl)
    } catch (error) {
      console.error('下载文件失败:', error)
      throw error
    }
  }

  /**
   * 预览文件
   */
  static async previewFile(url: string): Promise<string> {
    try {
      const response = await request.get(url, {
        responseType: 'blob'
      })

      return URL.createObjectURL(response.data)
    } catch (error) {
      console.error('预览文件失败:', error)
      throw error
    }
  }

  /**
   * 删除文件
   */
  static async deleteFile(url: string): Promise<void> {
    try {
      await request.delete('/common/file', {
        data: { url }
      })
    } catch (error) {
      console.error('删除文件失败:', error)
      throw error
    }
  }

  /**
   * 获取文件信息
   */
  static async getFileInfo(url: string): Promise<{
    name: string
    size: number
    type: string
    lastModified: string
  }> {
    try {
      const response = await request.get('/common/file/info', {
        params: { url }
      })
      return response.data
    } catch (error) {
      console.error('获取文件信息失败:', error)
      throw error
    }
  }

  /**
   * 验证文件类型
   */
  static validateFileType(file: File): boolean {
    return UPLOAD.ALLOWED_TYPES.includes(file.type)
  }

  /**
   * 验证文件大小
   */
  static validateFileSize(file: File): boolean {
    return file.size <= UPLOAD.MAX_SIZE
  }

  /**
   * 格式化文件大小
   */
  static formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 B'
    
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    
    return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`
  }

  /**
   * 获取文件扩展名
   */
  static getFileExtension(filename: string): string {
    return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2)
  }

  /**
   * 检查是否为图片文件
   */
  static isImageFile(file: File): boolean {
    return file.type.startsWith('image/')
  }

  /**
   * 检查是否为视频文件
   */
  static isVideoFile(file: File): boolean {
    return file.type.startsWith('video/')
  }

  /**
   * 检查是否为音频文件
   */
  static isAudioFile(file: File): boolean {
    return file.type.startsWith('audio/')
  }
}
